﻿#include "TestRecordManager.h"
#include "CDBConnector.h"
#include <QDebug>

#include <QUuid>
#include <QDateTime>

#define CURRENT_DATESTR QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")

#define CHECK_NEW_CODE_TIMES            5

using namespace zl;
TestRecordManager* zl::TestRecordManager::m_instance = nullptr;


TestRecordManager* zl::TestRecordManager::getInstance()
{
	if (!m_instance)
	{
        m_instance = new TestRecordManager();
	}
	return m_instance;
}

void zl::TestRecordManager::Release()
{
    qDebug() << "[WARNING]" << "release test record  manager...";
    delete m_instance;
    m_instance = nullptr;
}

TestRecordManager::TestRecordManager()
{

}

TestRecordManager::~TestRecordManager()
{

}

QString zl::TestRecordManager::GeneratedRecordID()
{
    QUuid id = QUuid::createUuid();
    QString cur_id =  id.toString();

//    cur_id.remove("-");
    cur_id.remove("{").remove("}");

    return cur_id;
}

void zl::TestRecordManager::GetEmptyRecord(RecordInfo& record)
{
    qDebug() << "[INFO]" << "empty record";

    record.record_id = GeneratedRecordID();

    record.account = "";
    record.name = "";

    record.action_time = "";
    record.action_type = ESNWT_ActionType_Unknow;
    record.result_type = ESNWT_ResultType_Unknow;

    record.describe = "";
    record.sn_info = "";

    record.confirmded = EConfirm_Type_Unknown;
}

int32_t zl::TestRecordManager::SaveTestRecord(RecordInfo& record)
{
    qDebug() << "[INFO]" << "save record: " << record.record_id;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("INSERT INTO T_RECORD (RECORD_ID, ACCOUNT, NAME, ACTION_TIME, ACTION_TYPE, RESULT_TYPE, RET_DETAIL, \
                    SN_INFO, CONFIRMED) \
        VALUES(:record_id, :account, :name, :action_time, :action_type, :result_type, :ret_detail, \
                    :sn_info, :confirmed)");

    query.bindValue(":record_id", record.record_id);
    query.bindValue(":account", record.account);
    query.bindValue(":name", record.name);
    query.bindValue(":action_time", CURRENT_DATESTR);
    query.bindValue(":action_type", record.action_type);
    query.bindValue(":result_type", record.result_type);
    query.bindValue(":ret_detail", record.describe);
    query.bindValue(":sn_info", record.sn_info);

    query.bindValue(":confirmed", record.confirmded);


    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "save record failed: " << ret;
        return EResult_Failed;
    }

    record.action_time = CURRENT_DATESTR;

    qDebug() << "[INFO]" << "save record success: " << record.record_id;
    return EResult_Success;
}

int32_t zl::TestRecordManager::RemoveTestRecords(const QStringList& record_id)
{
    qDebug() << "[INFO]" << "remove records, record id list size: " << record_id.size();

    if (record_id.isEmpty())
    {
        qDebug() << "[ERROR]" << "remove records error, record id list is empty";
        return EResult_Failed;
    }

    int list_size = record_id.size();

    QString tail;

    for (int i = 0; i < list_size; i++)
    {
        QString data = record_id.at(i);

        if (!data.isEmpty())
            tail += "?,";
        else
            qDebug() << "[ERROR]" << "remove records, one record id is empty";
    }

    tail.chop(1);        // 去掉多余的逗号

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();

    QString str = QString("DELETE FROM T_RECORD WHERE RECORD_ID IN(%1)").arg(tail);

    query.prepare(str);

    for (int i = 0; i < list_size; i++)
    {
        QString data = record_id.at(i);

        if (!data.isEmpty())
            query.bindValue(i, data);
    }

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "remove records failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "remove records success";
    return EResult_Success;
}

int32_t zl::TestRecordManager::SearchRecord(const QString& record_id)
{
    qDebug() << "[INFO]" << "search record info by record id: " << record_id;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("SELECT * FROM T_RECORD WHERE RECORD_ID=:record_id");
    query.bindValue(":record_id", record_id);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success || !query.next())
    {
        qDebug() << "[INFO]" << "record not found or query failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "search record info success: " << record_id;
    return EResult_Success;
}

int32_t zl::TestRecordManager::RemoveRecord(const QString& record_id)
{
    qDebug() << "[INFO]" << "remove record info by record id: " << record_id;

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    query.prepare("DELETE FROM T_RECORD WHERE RECORD_ID=:record_id");
    query.bindValue(":record_id", record_id);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[INFO]" << "remove record failed: " << ret;
        return EResult_Failed;
    }

    qDebug() << "[INFO]" << "remove record info success: " << record_id;
    return EResult_Success;
}

int32_t zl::TestRecordManager::GetAllRecord(RecordVec& vec,
        const QString& begin_time,
        const QString& close_time,
        const ESNWT_ActionType action_type,
        const ESNWT_ResultType result_type,
        const QString account,
        const QString sn_info,
        const EConfirm_Type confirmed)
{
    qDebug() << "[INFO]" << "query record";
    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();
    QString str = "SELECT * FROM T_RECORD WHERE ACTION_TIME>=:begin_time AND ACTION_TIME<:close_time";

    if (action_type > ESNWT_ActionType_Unknow) str += " AND ACTION_TYPE=:action_type";

    if (result_type > ESNWT_ResultType_Unknow) str += " AND RESULT_TYPE=:result_type";

    if (!account.isEmpty()) str += " AND ACCOUNT=:account";

    if (!sn_info.isEmpty()) str += " AND SN_INFO=:sn_info";

    if (confirmed > EConfirm_Type_Unknown) str += " AND CONFIRMED=:confirmed";

    str += " ORDER BY ACTION_TIME DESC";

    query.prepare(str);
    query.bindValue(":begin_time", begin_time);
    query.bindValue(":close_time", close_time);

    if (action_type > ESNWT_ActionType_Unknow) query.bindValue(":action_type", action_type);

    if (result_type > ESNWT_ResultType_Unknow) query.bindValue(":result_type", result_type);

    if (!account.isEmpty()) query.bindValue(":account", account);

    if (!sn_info.isEmpty()) query.bindValue(":sn_info", sn_info);

    if (confirmed > EConfirm_Type_Unknown) query.bindValue(":confirmed", confirmed);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[ERROR]" << "get all record, exec query failed: " << ret;
        return EResult_Failed;
    }

    while (query.next())
    {
        RecordInfo record;

        record.record_id = query.value("RECORD_ID").toString();

        record.account = query.value("ACCOUNT").toString();
        record.name = query.value("NAME").toString();
        record.action_time = query.value("ACTION_TIME").toString();

        record.action_type = ESNWT_ActionType(query.value("ACTION_TYPE").toInt());
        record.result_type = ESNWT_ResultType(query.value("RESULT_TYPE").toInt());
        record.describe = query.value("RET_DETAIL").toString();
        record.sn_info = query.value("SN_INFO").toString();

        record.confirmded = EConfirm_Type(query.value("CONFIRMED").toInt());

        vec.push_back(record);
    }

    qDebug() << "[INFO]" << "get all records success: " << vec.size();
    return EResult_Success;
}

int32_t zl::TestRecordManager::GetComboCompleterInfo(QStringList& account_list, QStringList& sn_info_list)
{
    qDebug() << "[INFO]" << "get combo completer info";

    QSqlQuery query = zl::CDBConnector::Instance()->CreateQuery();

    QString str = "SELECT ACCOUNT, SN_INFO FROM T_RECORD";

    query.prepare(str);

    int32_t ret = zl::CDBConnector::Instance()->ExecQuery(query);
    if (ret != zl::CDBConnector::EDBError_Success)
    {
        qDebug() << "[INFO]" << "get combo completer info, exec query failed: " << ret;
        return EResult_Failed;
    }

    QString account_info, sn_info;

    while (query.next())
    {
        account_info = query.value("ACCOUNT").toString();
        sn_info = query.value("SN_INFO").toString();

        if (!account_list.contains(account_info) && !account_info.isEmpty()) account_list.append(account_info);

        if (!sn_info_list.contains(sn_info) && !sn_info.isEmpty()) sn_info_list.append(sn_info);
    }

    qDebug() << "[INFO]" << "get combo completer info success";
    return EResult_Success;
}
